package com.github.linkoog.model_designer.utils;

import com.github.linkoog.model_designer.ide.editer.common.*;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.List;

public class DDLSqlUtil {

    public static String createDDLSql(@NotNull DbType dbType, @NotNull TableVo tableVo){
        StringBuilder builder = new StringBuilder();
        switch (dbType) {
            case MYSQL:
                builder.append("DROP TABLE IF EXISTS ").append("`").append(tableVo.getName()).append("`;\n");
                createMysqlDDL(builder, tableVo);
                break;
            case ORACLE:
                builder.append("DROP TABLE ").append("\"").append(tableVo.getName()).append("\";\n");
                createOracleDDL(builder, tableVo);
                break;
            case POSTGRE:
                builder.append("DROP TABLE IF EXISTS \"public\".").append("\"").append(tableVo.getName()).append("\";\n");
                createPostgreDDL(builder, tableVo);
                break;
        }
        return builder.toString();
    }

    /**
     */
    private static void createMysqlDDL(StringBuilder builder, TableVo tableVo){
        builder.append("CREATE TABLE ").append("`").append(tableVo.getName()).append("` (").append("\n");
        List<String> ids = new ArrayList<>();

        List<String> columnString = new ArrayList<>();
        List<? extends Column> columns = tableVo.getColumns();
        for (Column column : columns) {
            ColumnVo columnVo = column.getColumnVo();

            if (columnVo.getPrimaryKey() != null && columnVo.getPrimaryKey()){
                ids.add("`"+ column.getName() + "`");
            }

            StringBuilder columnBuilder = new StringBuilder();
            //设置列名
            columnBuilder.append("  `").append(column.getName()).append("` ");

            //设置数据类型
            DataType dataType = columnVo.getDataType() == null ? DataType.VARCHAR : columnVo.getDataType();
            if (dataType == DataType.CHAR || dataType == DataType.VARCHAR){
                columnBuilder.append(dataType.getName()).append("(").append(columnVo.getLength()).append(")").append(" COLLATE utf8mb4_bin ");
            } else if (dataType == DataType.TEXT){
                columnBuilder.append(dataType.getName()).append(" COLLATE utf8mb4_bin ");
            } else if (dataType == DataType.TINYINT || dataType == DataType.SMALLINT || dataType == DataType.INT || dataType == DataType.BIGINT){
                columnBuilder.append(dataType.getName()).append("(").append(columnVo.getLength()).append(") ");
            } else if (dataType == DataType.DECIMAL){
                columnBuilder.append(dataType.getName()).append("(").append(columnVo.getLength()).append(",").append(columnVo.getRadix()).append(") ");
            } else if (dataType == DataType.DATE || dataType == DataType.TIME || dataType == DataType.DATETIME){
                columnBuilder.append(dataType.getName()).append(" ");
            }

            //设置not null属性
            if ((columnVo.getPrimaryKey() != null && columnVo.getPrimaryKey())
                    || (columnVo.getNotNull() != null && columnVo.getNotNull())){
                columnBuilder.append("NOT NULL").append(" ");
            }

            //设置默认值
            if (StringUtils.isNotBlank(columnVo.getDefaultValue())){
                columnBuilder.append("DEFAULT ").append("'").append(columnVo.getDefaultValue()).append("' ");
            } else {
                if ( dataType == DataType.CHAR || dataType == DataType.VARCHAR || dataType == DataType.TEXT
                        ||dataType == DataType.DATE || dataType == DataType.TIME || dataType == DataType.DATETIME){
                    if (columnVo.getNotNull() == null || !columnVo.getNotNull()){
                        columnBuilder.append("DEFAULT NULL ");
                    }
                }
            }

            //设置列的注释
            if (StringUtils.isNotBlank(columnVo.getComment())){
                columnBuilder.append("COMMENT ").append("'").append(columnVo.getComment()).append("' ");
            }

            columnString.add(columnBuilder.toString());
        }

        //处理表的主键
        if (!ids.isEmpty()){
            for (String s : columnString) {
                builder.append(s).append(",\n");
            }

            builder.append("  PRIMARY KEY (").append(String.join(",", ids)).append(")\n");
        } else {
            for (int i = 0; i < columnString.size(); i++) {
                String s = columnString.get(i);
                if (i != columnString.size() -1){
                    builder.append(s).append(",\n");
                } else {
                    builder.append(s).append("\n");
                }
            }
        }

        builder.append(") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin");
        if (StringUtils.isNotBlank(tableVo.getComment())){
            builder.append(" COMMENT=").append("'").append(tableVo.getComment()).append("'");
        }
        builder.append(";\n");
    }

    private static void createOracleDDL(StringBuilder builder, TableVo tableVo){
        builder.append("CREATE TABLE ").append("\"").append(tableVo.getName()).append("\" (").append("\n");

        List<String> ids = new ArrayList<>();
        List<String> columnString = new ArrayList<>();
        List<String> columnComments = new ArrayList<>();
        List<? extends Column> columns = tableVo.getColumns();
        for (Column column : columns) {
            ColumnVo columnVo = column.getColumnVo();

            if (columnVo.getPrimaryKey() != null && columnVo.getPrimaryKey()) {
                ids.add("\"" + column.getName() + "\"");
            }

            StringBuilder columnBuilder = new StringBuilder();
            //设置列名
            columnBuilder.append("  \"").append(column.getName()).append("\" ");

            //设置数据类型
            DataType dataType = columnVo.getDataType() == null ? DataType.VARCHAR : columnVo.getDataType();
            if (dataType == DataType.CHAR ){
                columnBuilder.append("CHAR").append("(").append(columnVo.getLength()).append(")").append(" ");
            }else if (dataType == DataType.VARCHAR){
                columnBuilder.append("VARCHAR2").append("(").append(columnVo.getLength()).append(")").append(" ");
            } else if (dataType == DataType.TEXT){
                columnBuilder.append("VARCHAR2(4000)").append(" ");
            } else if (dataType == DataType.TINYINT){
                columnBuilder.append("NUMBER(8)").append(" ");
            } else if (dataType == DataType.SMALLINT){
                columnBuilder.append("NUMBER(16)").append(" ");
            } else if (dataType == DataType.INT){
                columnBuilder.append("NUMBER(32)").append(" ");
            } else if (dataType == DataType.BIGINT){
                columnBuilder.append("NUMBER").append(" ");
            } else if (dataType == DataType.DECIMAL){
                columnBuilder.append("NUMBER").append("(").append(columnVo.getLength()).append(",").append(columnVo.getRadix()).append(") ");
            } else if (dataType == DataType.DATE ){
                columnBuilder.append("DATE").append(" ");
            } else if (dataType == DataType.TIME ){
                columnBuilder.append("DATE").append(" ");
            } else if (dataType == DataType.DATETIME ){
                columnBuilder.append("TIMESTAMP").append(" ");
            }

            //设置not null属性
            if ((columnVo.getPrimaryKey() != null && columnVo.getPrimaryKey())
                    || (columnVo.getNotNull() != null && columnVo.getNotNull())){
                columnBuilder.append("NOT NULL").append(" ");
            }

            //设置默认值
            if (StringUtils.isNotBlank(columnVo.getDefaultValue())){
                columnBuilder.append("DEFAULT ").append(columnVo.getDefaultValue()).append(" ");
            }

            //设置列的注释
            if (StringUtils.isNotBlank(columnVo.getComment())){
                String s = "COMMENT ON COLUMN \"" + tableVo.getName() + "\"." +
                        "\"" + columnVo.getName() + "\"" + " IS " + "'" + columnVo.getComment() + "';";
                columnComments.add(s);
            }

            columnString.add(columnBuilder.toString());
        }

        //处理表的主键
        if (!ids.isEmpty()){
            for (String s : columnString) {
                builder.append(s).append(",\n");
            }

            builder.append("  CONSTRAINT \"").append(tableVo.getName()).append("_pkey\" PRIMARY KEY (").append(String.join(",", ids)).append(")\n");
        } else {
            for (int i = 0; i < columnString.size(); i++) {
                String s = columnString.get(i);
                if (i != columnString.size() -1){
                    builder.append(s).append(",\n");
                } else {
                    builder.append(s).append("\n");
                }
            }
        }
        builder.append(");\n");

        if (StringUtils.isNotBlank(tableVo.getComment())){
            builder.append("\n")
                    .append("COMMENT ON TABLE \"").append(tableVo.getName()).append("\"")
                    .append(" IS ").append("'").append(tableVo.getComment()).append("';\n");
        }

        for (String columnComment : columnComments) {
            builder.append("\n").append(columnComment).append("\n");
        }

    }

    private static void createPostgreDDL(StringBuilder builder, TableVo tableVo){
        builder.append("CREATE TABLE \"public\".").append("\"").append(tableVo.getName()).append("\" (").append("\n");

        List<String> ids = new ArrayList<>();
        List<String> columnString = new ArrayList<>();
        List<String> columnComments = new ArrayList<>();
        List<? extends Column> columns = tableVo.getColumns();
        for (Column column : columns) {
            ColumnVo columnVo = column.getColumnVo();

            if (columnVo.getPrimaryKey() != null && columnVo.getPrimaryKey()){
                ids.add("\""+ column.getName() + "\"");
            }

            StringBuilder columnBuilder = new StringBuilder();
            //设置列名
            columnBuilder.append("  \"").append(column.getName()).append("\" ");

            //设置数据类型
            DataType dataType = columnVo.getDataType() == null ? DataType.VARCHAR : columnVo.getDataType();
            if (dataType == DataType.CHAR || dataType == DataType.VARCHAR){
                columnBuilder.append(dataType.getName()).append("(").append(columnVo.getLength()).append(")").append(" COLLATE \"pg_catalog\".\"default\" ");
            } else if (dataType == DataType.TEXT){
                columnBuilder.append(dataType.getName()).append(" COLLATE \"pg_catalog\".\"default\" ");
            } else if (dataType == DataType.TINYINT){
                columnBuilder.append("int2").append(" ");
            } else if (dataType == DataType.SMALLINT){
                columnBuilder.append("int2").append(" ");
            } else if (dataType == DataType.INT){
                columnBuilder.append("int4").append(" ");
            } else if (dataType == DataType.BIGINT){
                columnBuilder.append("int8").append(" ");
            } else if (dataType == DataType.DECIMAL){
                columnBuilder.append("numeric").append("(").append(columnVo.getLength()).append(",").append(columnVo.getRadix()).append(") ");
            } else if (dataType == DataType.DATE ){
                columnBuilder.append("date").append(" ");
            } else if (dataType == DataType.TIME ){
                columnBuilder.append("time(6)").append(" ");
            } else if (dataType == DataType.DATETIME ){
                columnBuilder.append("timestamp(6)").append(" ");
            }

            //设置not null属性
            if ((columnVo.getPrimaryKey() != null && columnVo.getPrimaryKey())
                    || (columnVo.getNotNull() != null && columnVo.getNotNull())){
                columnBuilder.append("NOT NULL").append(" ");
            }

            //设置默认值
            if (StringUtils.isNotBlank(columnVo.getDefaultValue())){
                columnBuilder.append("DEFAULT ").append(columnVo.getDefaultValue()).append(" ");
            }

            //设置列的注释
            if (StringUtils.isNotBlank(columnVo.getComment())){
                String s = "COMMENT ON COLUMN \"public\"." + "\"" + tableVo.getName() + "\"." +
                        "\"" + columnVo.getName() + "\"" + " IS " + "'" + columnVo.getComment() + "';";
                columnComments.add(s);
            }

            columnString.add(columnBuilder.toString());
        }

        //处理表的主键
        if (!ids.isEmpty()){
            for (String s : columnString) {
                builder.append(s).append(",\n");
            }

            builder.append("  CONSTRAINT \"").append(tableVo.getName()).append("_pkey\" PRIMARY KEY (").append(String.join(",", ids)).append(")\n");
        } else {
            for (int i = 0; i < columnString.size(); i++) {
                String s = columnString.get(i);
                if (i != columnString.size() -1){
                    builder.append(s).append(",\n");
                } else {
                    builder.append(s).append("\n");
                }
            }
        }

        builder.append(");\n");
        builder.append("ALTER TABLE \"public\".").append("\"").append(tableVo.getName()).append("\"").append(" OWNER TO \"postgres\";\n");

        if (StringUtils.isNotBlank(tableVo.getComment())){
            builder.append("\n")
                    .append("COMMENT ON TABLE \"public\".\"").append(tableVo.getName()).append("\"")
                    .append(" IS ").append("'").append(tableVo.getComment()).append("';\n");
        }

        for (String columnComment : columnComments) {
            builder.append("\n").append(columnComment).append("\n");
        }
    }


}
